function fn1(a, b) {
  console.log('this : ', this);
  console.log(a, b);
  return a + b;
}

// const result = fn1(1, 2);
// console.log(result);

// const fn2 = fn1.bind({name: 'yibo'});
// const result = fn2(1, 2);

// 自己实现bind方法
Function.prototype.bind2 = function () {
  const _this = this; // 这是函数对象的this
  const arr = Array.prototype.slice.call(arguments);
  const t = arr.shift();
  return function () {
    return _this.apply(t, arr);
  }
}
// const fn2 = fn1.bind2({name: 'yibo'}, 6, 7);
// const result = fn2();
// console.log(result);

// 自己实现call方法
Function.prototype.myCall = function (context) {
  if(context == null){
    context = window;
  }
  context.fn = this;
  const arg = [...arguments].slice(1);
  const ret = context.fn(...arg);
  delete context.fn;
  return ret;
}

// const result = fn1.myCall({name: 'jal'}, 150, 100);
// console.log(result);

// 自己实现apply方法
Function.prototype.myApply = function (context, arr) {
  if(context == null) {
    context = window;
  }
  context.fn = this;
  let ret;
  if(arr == null){
    ret = context.fn();
  }else {
    ret = context.fn(...arr);
  }
  delete context.fn;
  return ret;
}

// const result = fn1.myApply({name: 'cathy'}, [2, 4]);
// console.log(result);

// 自己实现bind方法
Function.prototype.myBind = function (context) {
  if(context == null){
    context = window;
  }
  const arg = [...arguments].slice(1);
  const _this = this;
  
  return function F () {
    if(this instanceof F) {
      return _this.call(this, ...arg);
    }
    return _this.call(context, ...arg);
  }
}

// const fn2 = fn1.myBind({name: 'yibo'}, 6, 7);
// const result = fn2();
// console.log(result);

function f() {
  const data = {};
  return {
    get: function (key) {
      return data[key];
    },
    set: function (key, value) {
      data[key] = value
    }
  }
}

const cache = f();
cache.set('name', 'yibo');
console.log(cache.get('name'));


